package com.yonyou.crm.sprc.opportunity.appctrl;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.yonyou.crm.base.doc.rmitf.IBaseDocRmService;
import com.yonyou.crm.bpub.list.entity.*;
import com.yonyou.crm.common.base.AppBaseCtrl;
import com.yonyou.crm.common.exception.CrmMessageException;
import com.yonyou.crm.common.page.entity.Page;
import com.yonyou.crm.common.rest.apputil.AppRequestUtil;
import com.yonyou.crm.common.rest.constant.AppCodeConstant;
import com.yonyou.crm.common.rest.util.RequestUtil;
import com.yonyou.crm.common.rest.util.ResponseUtil;
import com.yonyou.crm.common.sort.entity.AppSortPlanEnum;
import com.yonyou.crm.sprc.opportunity.entity.*;
import com.yonyou.crm.sprc.opportunity.rmitf.IOpportunityRmService;

@RestController
@RequestMapping(value = "/{version}/msprc/opportunities")
public class AppOpportunityCtrl extends AppBaseCtrl {

    @Autowired
    private IOpportunityRmService service;
    
    @Autowired
    private IBaseDocRmService docService;
	
    /**
     * 新增与编辑
     * @param version
     * @param id
     * @param request
     * @param response
     * @return
     * @throws CrmMessageException
     */
	@RequestMapping(value="/{id}", method = RequestMethod.POST)
	public Object save(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		JSONObject dataJsonObject = AppRequestUtil.getFormParamObject(request);

		OpportunityVO opportunityVO = RequestUtil.getVO(dataJsonObject.getJSONObject("header"), OpportunityVO.class);
		String errorMsg = insertValidator(opportunityVO);
		if (!errorMsg.equals("")) {
			throw new CrmMessageException(AppCodeConstant.ServerError, errorMsg);
		}
		
		JSONObject bodyJsonObject =dataJsonObject.getJSONObject("body");
		
		JSONArray bodyJsonArray = bodyJsonObject.getJSONArray("product1");
		List<OpportunityBVO> opportunityBVOs = RequestUtil.getVOList(bodyJsonArray, OpportunityBVO.class);
		opportunityVO.setChildList(opportunityBVOs);

		Map<String, Object> param = new HashMap<String, Object>();
		setBizType(dataJsonObject, param);
		
		if (id.equals(0L)) {
			//relateMap标识是否有关联业务的新增
			Map<String, String> relateMap = (Map<String, String>)dataJsonObject.getJSONObject("relateMap");
			if ( relateMap != null) {
				param.put("relateMap", relateMap);
				opportunityVO = service.insert(opportunityVO, param);
			} else {
				opportunityVO = service.insert(opportunityVO);
			}
		} else {
			opportunityVO.setId(id);
			opportunityVO = service.update(opportunityVO);
		}
		
		if (opportunityVO.getId() == null) {
			throw new CrmMessageException(AppCodeConstant.ServerError, "获取自增主键失败，未保存成功");
		}
		return ResponseUtil.getObject();
	}
	
	/**
	 * 数据校验
	 * @param opportunity
	 * @return
	 */
	private String insertValidator(OpportunityVO opportunity){
		String Message = "";
		if (opportunity == null) {
			Message = "商机实体转换失败";
		}
		if (!StringUtils.isNotBlank(opportunity.getName())) {
			Message = "商机名称不能为空";
        }
		return Message;
	}
	
	/**
	 * 列表
	 * @param version
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(method = RequestMethod.GET)
	public Object getList(@PathVariable("version") String version, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		JSONObject paramObject = RequestUtil.getParamObject(request);
		int page = paramObject.getInt("page");
		int pageSize = paramObject.getInt("pageSize");
		checkPageInfo(page, pageSize);
		Page<OpportunityVO> pageInfo = new Page<OpportunityVO>(page, pageSize);
		
		Map<String, Object> searchMap = new HashMap<String, Object>();
		getSearchKeyForList(paramObject, searchMap); //搜索关键字
		getFilterForList(paramObject, searchMap); //列表筛选
		getOptionForList(paramObject, searchMap); //列表数据分类
		getSortOrderForPage(paramObject, pageInfo); //排序依据
			
		Page<OpportunityVO> pagelist = service.getList(pageInfo, searchMap);
		List<OpportunityVO> dataList = pagelist.getData();
    	List<AppListVO> list = new ArrayList<AppListVO>();
    	
    	if (dataList != null) {
    		for (int i = 0; i<dataList.size(); i++) {
    			OpportunityVO opp = dataList.get(i);
    			AppListVO listVO = tranVoToAppListVO(opp);
    			list.add(listVO);
    		}
    	}
		
		Map<String, Object> map = new HashMap<String,Object>();
		map.put("list", list);
		return ResponseUtil.getObject(map);
	}
	
	/**
	 * 将数据转化为App列表数据
	 * @param opp
	 * @return
	 * @throws CrmMessageException
	 */
	public AppListVO tranVoToAppListVO(OpportunityVO opp) throws CrmMessageException {
		AppListVO listVO = new AppListVO();
		listVO.setId(opp.getId());
		
		//左右两侧图标
		List<AppListSpecialVO> specialList = new ArrayList<>();
		getAppListSpecialVO(opp, specialList);
		listVO.setSpeciallist(specialList);

		List<List<AppListValueVO>> valueList = new ArrayList<>();
		List<AppListValueVO> colList = new ArrayList<>();
		AppListValueVO listValue;
		
		listValue = new AppListValueVO();
		listValue.setItemkey("name");
		listValue.setDisplayvalue(opp.getName());
		colList.add(listValue);
		
		valueList.add(colList);
		colList = new ArrayList<>();
		
		listValue = new AppListValueVO();
		listValue.setItemkey("stage");
		listValue.setDisplayvalue((opp.getSaleStageName() == null) ? "" : opp.getSaleStageName());
		colList.add(listValue);
		
		listValue = new AppListValueVO();
		listValue.setItemkey("stagestaytime");
		//根据阶段开始时间计算阶段停留时间
		Date stageStartTime = opp.getStageStartTime();
		String stagestaytime = getDataRangeStr(stageStartTime);
		listValue.setDisplayvalue(stagestaytime);
		colList.add(listValue);
		
		valueList.add(colList);
		colList = new ArrayList<>();

		listValue = new AppListValueVO();
		listValue.setItemkey("predicttime");
		String displayValue = opp.getExpectSignTime() == null ? "" : formateDate(opp.getExpectSignTime(), "yyyy-MM-dd");
		listValue.setDisplayvalue(displayValue);
		colList.add(listValue);
		
		listValue = new AppListValueVO();
		listValue.setItemkey("price");
		listValue.setDisplayvalue("¥"+((opp.getExpectSignMoney() == null) ? "" : opp.getExpectSignMoney()));
		colList.add(listValue);
		
		valueList.add(colList);
		colList = new ArrayList<>();
		
		listValue = new AppListValueVO();
		listValue.setItemkey("department");
		listValue.setDisplayvalue((opp.getDeptName() == null) ? "" : opp.getDeptName());
		colList.add(listValue);
		
		listValue = new AppListValueVO();
		listValue.setItemkey("ownerUser");
		listValue.setDisplayvalue((opp.getOwnerUserName() == null) ? "" : opp.getOwnerUserName());
		colList.add(listValue);
		
		valueList.add(colList);
		
		listVO.setValuelist(valueList);
		return listVO;
	}
	
	/**
	 * 列表左右两侧图标
	 * @param opp
	 * @param specialList
	 */
	private void getAppListSpecialVO(OpportunityVO opp, List<AppListSpecialVO> specialList) {
		AppListSpecialVO icon;
		
		icon = new AppListSpecialVO();
		icon.setType("percent");
		icon.setPosition("left");
		icon.setValue(opp.getWinProbability());
		specialList.add(icon);
	}
	
	/**
	 * 根据阶段开始时间计算阶段停留时间
	 * @param stageStartTime
	 * @return
	 */
	private String getDataRangeStr(Date stageStartTime) {
		Date now = new Date();
		String stagestaytime = "0天0小时";
		if (stageStartTime != null) {
			long timeRange = now.getTime() - stageStartTime.getTime();
			if (timeRange != 0) {
				long days = timeRange/(1000 * 60 * 60 * 24);
				long hours = (timeRange-days*(1000 * 60 * 60 * 24))/(1000* 60 * 60);
				if (days == 0 && hours == 0) {
					stagestaytime = "0天1小时";
				} else {
					stagestaytime = days + "天" + hours + "小时";
				}
			}
		}
		return stagestaytime;
	}
	
	/**
	 * 排序依据
	 * @param paramObject
	 * @param pageInfo
	 * @throws CrmMessageException
	 */
	private void getSortOrderForPage(JSONObject paramObject, Page<OpportunityVO> pageInfo) throws CrmMessageException {
		String sortStr = "";
		String orderStr = "";
		Map<String, String> sortInfo = new HashMap<>();
		getSortForList(paramObject, sortInfo);
		if ((sortInfo != null) && (sortInfo.size() > 0)) {
			orderStr = String.valueOf(sortInfo.get("order"));
			Integer sortNum = Integer.valueOf(String.valueOf(sortInfo.get("field")));
			if (sortNum == AppSortPlanEnum.WINPROBABILITY.getValue()) {
				sortStr = "opportunity.win_probability";
			} else if (sortNum == AppSortPlanEnum.EXPECTEDSIGNTIME.getValue()) {
				sortStr = "opportunity.expect_sign_time";
			} else if (sortNum == AppSortPlanEnum.EXPECTEDSIGNAMOUNT.getValue()) {
				sortStr = "opportunity.expect_sign_money";
			} else if (sortNum == AppSortPlanEnum.MODIFYTIME.getValue()) {
				sortStr = "opportunity.sys_modified_time";
			} else {
				sortStr = "opportunity.id";
				orderStr = "desc";
			}
		}
		pageInfo.setSort(sortStr);
		pageInfo.setOrder(orderStr);
	}
	
	/**
	 * 删除
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "{id}", method = RequestMethod.DELETE)
	public Object delete(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) {
		service.delete(id);
		return ResponseUtil.getObject();
	}
	
	/**
	 * 阶段信息
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "{id}/stages", method = RequestMethod.GET)
	public Object stages(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) {
		List<AppOpportunityStageVO> stageList = service.getStageListForOpportunity(id);
		Map<String, Object> res = new HashMap<>();
		res.put("stagelist", stageList);
		return ResponseUtil.getObject(res);
	}
	
	/**
	 *  修改阶段
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "{id}/stages", method = RequestMethod.PUT)
	public Object saveStages(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) {
		JSONObject paramObject = RequestUtil.getParamObject(request);
		String stageId = paramObject.getString("stageid");
		
		Map<String, Object> param = new HashMap<>();
		param.put("stageId",stageId);
		param.put("id",id);
		List<AppOpportunityStageVO> stageList = service.stageInfo(param);
		Map<String, Object> res = new HashMap<>();
		res.put("stagelist", stageList);
		return ResponseUtil.getObject(res);
	}
	
	/**
	 * 修改动作
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "{id}/actions", method = RequestMethod.PUT)
	public Object saveActions(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) {
		JSONObject paramObject = RequestUtil.getParamObject(request);
		String stageId = paramObject.getString("stageid");
		String dimensionId = paramObject.getString("dimensionid");
		String actionId = paramObject.getString("actionid");
		String isSelected = (paramObject.getString("action").equals("Y")) ? "1" : "2";
		
		Map<String, Object> param = new HashMap<>();
		param.put("stageId",stageId);
		param.put("dimensionId",dimensionId);
		param.put("actionId",actionId);
		param.put("isSelected",isSelected);
		param.put("opportunityId",id);
		service.saveAction(param);
		return ResponseUtil.getObject();
	}

	/**
	 * 关注
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(value="/{id}/follow", method = RequestMethod.PUT)
	public Object follow(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		
		JSONObject paramObject = RequestUtil.getParamObject(request);
		String followState = paramObject.getString("followState");
		
		if (id == null) {
			throw new CrmMessageException(AppCodeConstant.ClientError, "商机id不能为空");
		}
		
		if (followState.equals("N")) {
			service.deleteFollow(id);
		} else if (followState.equals("Y")) {
			service.insertFollow(id);
		} else {
			throw new CrmMessageException(AppCodeConstant.ClientError, "非法商机关注标识");
		}

		return ResponseUtil.getObject();
	}

	/**
	 * 赢单
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(value="/{id}/win", method = RequestMethod.PUT)
	public Object win(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		
		if (id == null) {
			throw new CrmMessageException(AppCodeConstant.ClientError, "商机id不能为空");
		}
		
		JSONObject paramObject = RequestUtil.getParamObject(request);
		String remark = paramObject.getString("remark");
		Integer reason = Integer.valueOf(paramObject.getString("reason"));
		String actualSignDateStr = paramObject.getString("actualsigndate");
		Date actualSignDate = transformDateFromStr(actualSignDateStr, "yyyy-MM-dd");
		Float actualSignMoney = Float.valueOf(paramObject.getString("actualsignmoney"));
		
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("id", id);
		paramMap.put("remark", remark);
		paramMap.put("reason", reason);
		paramMap.put("actualSignDate", actualSignDate);
		paramMap.put("actualSignMoney", actualSignMoney);

		service.win(paramMap);

		return ResponseUtil.getObject();
	}

	/**
	 * 输单
	 * @param version
	 * @param id
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(value="/{id}/lose", method = RequestMethod.PUT)
	public Object lose(@PathVariable("version") String version, @PathVariable("id") Long id, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		
		if (id == null) {
			throw new CrmMessageException(AppCodeConstant.ClientError, "商机id不能为空");
		}
		
		JSONObject paramObject = RequestUtil.getParamObject(request);
		String remark = paramObject.getString("remark");
		Integer reason = Integer.valueOf(paramObject.getString("reason"));
		
		Map<String, Object> paramMap = new HashMap<>();
		paramMap.put("id", id);
		paramMap.put("remark", remark);
		paramMap.put("reason", reason);

		service.lose(paramMap);

		return ResponseUtil.getObject();
	}
	
	/**
	 * 获取赢单原因列表
	 * @param version
	 * @param request
	 * @param response
	 * @return
	 * @throws CrmMessageException
	 */
	@RequestMapping(value="/reason", method = RequestMethod.GET)
	public Object reason(@PathVariable("version") String version, HttpServletRequest request, HttpServletResponse response) throws CrmMessageException {
		
		JSONObject paramObject = RequestUtil.getParamObject(request);
		String type = paramObject.getString("type");
		Map<String, Object> idsMap = new HashMap<>();
		String reasonId = "";
		String reasonName = "";
		if ("win".equals(type)) {
			reasonId = "15";
			reasonName = "opportunity_win_reason";
		} else if ("lose".equals(type)) {
			reasonId = "16";
			reasonName = "opportunity_lose_reason";
		} else {
			throw new CrmMessageException(AppCodeConstant.ClientError, "商机原因类型错误");
		}
		
		idsMap.put(reasonId, reasonName);
		Map<String, Object> list = docService.getDocAndDetailList(idsMap);
		Map<String, Object> res = new HashMap<>();
		res.put("list", list.get(reasonName));
		
		return ResponseUtil.getObject(res);
	}
	
}
